#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <wiringPi.h>
#include "libxively/xively.h"
#include "libxively/xi_helpers.h"
#include "libxively/xi_err.h"


#define LED 8

sem_t Semaphore;

void digitalWriteToggle(unsigned char PinNo)
{
	static unsigned char Cnt;
	Cnt++;
	if(Cnt & 1){
		digitalWrite (PinNo, 1) ;
	}
	else{
		digitalWrite (PinNo, 0) ;	
	}
}


void* Thread1(void *data)
{
	(void)piHiPri (10) ;
	for (;;)
	{
		printf("1"); fflush(stdout);
		digitalWriteToggle(LED);
		usleep(500*1000); //500ms 동안 대기
	}
}

void* Thread2(void *data)
{
	(void)piHiPri (10) ;
	for (;;)
	{
		printf("2"); fflush(stdout);
		sem_post(&Semaphore);
		sleep(5);
	}
}


#define xi_api_key	"MNC8cY50oQDZ6ObQ8vdbmmOg01il4KwDWqhaArCURXh8NTAk"
#define xi_feed_id	1989666334
#define xi_datastream_id0 "led"
#define xi_datastream_id1 "light"

#if 0
void* Thread3(void *data)
{
	(void)piHiPri (10) ;
	volatile unsigned char value=77;
	
	// create the xi library context
	xi_context_t* xi_context = xi_create_context(XI_HTTP, xi_api_key, xi_feed_id );
	
	// check if everything works
	if( xi_context == 0 )
	{
		printf("Error\n");
		//return -1;
	}
	
	xi_datapoint_t datapoint;	
	
	for (;;)
	{
		printf("[");fflush(stdout);
		sem_wait(&Semaphore);

		xi_set_value_i32( &datapoint, value);
	
		// get actual timestamp
		time_t timer = 0;
		time( &timer );
		datapoint.timestamp.timestamp = timer;
		
		printf(">");fflush(stdout);
		
		xi_datastream_update(xi_context, xi_feed_id, xi_datastream_id0, &datapoint );

		printf( "]value=%d, ", value);
		printf( "err: %d - %s\n", ( int ) xi_get_last_error(), xi_get_error_string( xi_get_last_error() ) ); fflush(stdout);

		value++;
	}
	
	// destroy the context cause we don't need it anymore
	xi_delete_context( xi_context );
}

#else
void* Thread3(void *data)
{
	(void)piHiPri (10) ;
	volatile unsigned char value=77;
	
	// create the xi library context
	xi_context_t* xi_context = xi_create_context(XI_HTTP, xi_api_key, xi_feed_id );
	
	// check if everything works
	if( xi_context == 0 )
	{
		printf("Error\n");
		//return -1;
	}
	
	xi_datapoint_t* datapoint;
	xi_feed_t feed;
    memset( &feed, 0, sizeof( xi_feed_t ));
	feed.feed_id = xi_feed_id;
    feed.datastream_count = 2;
	for (;;)
	{
		printf("[");fflush(stdout);
		sem_wait(&Semaphore);
		
		//Datastream0
		feed.datastreams[0].datapoint_count=1;
		xi_str_copy_untiln(feed.datastreams[0].datastream_id, sizeof(xi_datastream_id0), xi_datastream_id0, '\0' );
		datapoint = (xi_datapoint_t*)&feed.datastreams[0].datapoints;
		xi_set_value_i32(datapoint, value);
		
		//Datastream1
		feed.datastreams[1].datapoint_count=1;
		xi_str_copy_untiln(feed.datastreams[1].datastream_id, sizeof(xi_datastream_id1), xi_datastream_id1, '\0' );
		datapoint = (xi_datapoint_t*)&feed.datastreams[1].datapoints;
		xi_set_value_i32(datapoint, 0xff-value);
		
		printf(">");fflush(stdout);
		
		xi_feed_update(xi_context, &feed);

		printf( "]value=%d, ", value);
		printf( "err: %d - %s\n", ( int ) xi_get_last_error(), xi_get_error_string( xi_get_last_error() ) ); fflush(stdout);

		value++;
	}
	
	// destroy the context cause we don't need it anymore
	xi_delete_context( xi_context );
}
#endif

void setup (void)
{
	pthread_t p_thread[3];
	
	wiringPiSetup();
	pinMode (LED, OUTPUT) ;

	sem_init(&Semaphore, 0, 0);
	pthread_create(&p_thread[0], NULL, Thread1, NULL);
    pthread_create(&p_thread[1], NULL, Thread2, NULL);
	pthread_create(&p_thread[2], NULL, Thread3, NULL);
	pthread_detach(p_thread[0]);
    pthread_detach(p_thread[1]); 
    pthread_detach(p_thread[2]);
}

int main (void)
{
	printf("\n Start...\n"); fflush(stdout);
	setup();

	for (;;)
	{
		printf("m"); fflush(stdout);
		sleep(1);
		//delay (1000);
	}
	
	pause();
	printf("\n End...\n"); fflush(stdout);
	return 0 ;
}
